/**
 * 
 */
package com.toncen.samepms.common;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import ognl.Ognl;
import ognl.OgnlContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.toncen.samepms.basic.domain.User;
import com.toncen.samepms.system.domain.Advice;
import com.sky.common.ognl.OgnlUtils;
import com.sky.common.string.StringUtils;

/**
 * 描述：抽象通知发布者
 * 
 * @author tch
 * 
 */
public abstract class AbstractAdviceDispatcher {
	protected Log logger = LogFactory.getLog(this.getClass());

	/**
	 * 标签起始标记
	 */
	public static final String USER_START_TAG = "#{";

	/**
	 * 标签结束标记
	 */
	public static final String USER_END_TAG = "}#";

	/**
	 * 发送者参数名称
	 */
	public static final String FROM_PARAMETER_NAME = "from";

	/**
	 * 接受者参数名称
	 */
	public static final String TO_PARAMETER_NAME = "to";

	/**
	 * 发送成功标志
	 */
	public static final int SUCCESSFUL = 1;

	/**
	 * 发送失败标志
	 */
	public static final int UNSUCCESSFUL = -1;

	/**
	 * 无发送标识
	 */
	public static final int VOID = 0;

	/**
	 * 
	 */
	public AbstractAdviceDispatcher() {

	}

	/**
	 * 获取包装的主题
	 * 
	 * @param fromUser
	 * @param toUser
	 * @param subject
	 * @return
	 * @throws Exception
	 */
	protected String getWrapSubject(User fromUser, User toUser, String subject) throws Exception {
		subject = getWrapConfigation(fromUser, toUser, subject);
		return subject;
	}

	/**
	 * 获取包装的内容
	 * 
	 * @param fromUser
	 * @param toUser
	 * @param content
	 * @return
	 * @throws Exception
	 */
	protected String getWrapContent(User fromUser, User toUser, String content) throws Exception {
		content = getWrapConfigation(fromUser, toUser, content);
		return content;
	}

	/**
	 * 获取包装的配置内容
	 * 
	 * @param fromUser
	 * @param toUser
	 * @param content
	 * @return
	 * @throws Exception
	 */
	private String getWrapConfigation(User fromUser, User toUser, String content) throws Exception {
		if (!StringUtils.isEmpty(content) && toUser != null) {
			Set<String> expressionSet = StringUtils.getAllTag(content, USER_START_TAG, USER_END_TAG);
			OgnlContext context = (OgnlContext) Ognl.createDefaultContext(null);
			Map<String, Object> root = new HashMap<String, Object>();
			root.put(FROM_PARAMETER_NAME, fromUser);
			root.put(TO_PARAMETER_NAME, toUser);
			Object value;
			for (String expression : expressionSet) {
				value = OgnlUtils.getValue(expression, context, root);
				content = StringUtils.replaceAll(content, getFullExpression(expression), value.toString());
			}
		}
		return content;
	}

	/**
	 * 获取完整表达式
	 * 
	 * @param expression
	 * @return
	 */
	private String getFullExpression(String expression) {
		return USER_START_TAG + expression + USER_END_TAG;
	}

	/**
	 * 获取通知发送者方式
	 * 
	 * @return
	 */
	public abstract int getMode();

	/**
	 * 当前用户对当前通知类型是否允许此中通知方式
	 * 
	 * @param user
	 * @param advice
	 * @return
	 */
	public abstract boolean accept(User user, Advice advice);

	/**
	 * 发送通知
	 * 
	 * @param advice
	 *            通知
	 * @param fromUser
	 *            发送者
	 * @param toUsers
	 *            接收者
	 * @param subject
	 *            通知主题
	 * @param content
	 *            通知内容
	 * 
	 * @return
	 * @throws Exception
	 */
	public abstract int send(Advice advice, final User fromUser, final Set<User> toUsers, String subject, String content) throws Exception;

	/**
	 * 发送通知
	 * 
	 * @param target
	 *            接收对象
	 * @param subject
	 *            通知主题
	 * @param content
	 *            通知内容
	 * @return
	 * @throws Exception
	 */
	public abstract boolean send(User target, String subject, String content) throws Exception;
}
